<?php
// +----------------------------------------------------------------------
// | 日志分类模型
// +----------------------------------------------------------------------
// | @link ( http://www.yurnero.net )
// +----------------------------------------------------------------------
// | @copyright
// +----------------------------------------------------------------------
// | @licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | @author Haijun Wu <nicholasinlove@126.com>
// +----------------------------------------------------------------------
// | $Id: CategoryModel.class.php 26 2011-02-15 05:48:40Z nicholasinlove1986@gmail.com $
// +----------------------------------------------------------------------


class CategoryModel extends Model {

	protected $catString = '';
	protected $catUrlString = array();
	
	public $_validate	=	array(
		array('category_title','require','{%category_title_require}'),
		array('category_url','require','{%category_url_require}'),
		array('category_sort','require','{%category_sort_require}'),
		array('category_title','','{%category_title_unique}',0,'unique',1),
		array('category_url','','{%category_url_unique}',0,'unique',1),
	);

	public $_auto		=	array(
		array('category_addtime','time',3,'function'),
		array('category_url','gdToEncode',3,'callback'),
	);
	
	//编码
	protected function gdToEncode() {
		$str = $_POST['category_url'];
		if (is_gb($str)) {
			return strtolower(urlencode($str));
		} else {
			return strtolower($str);
		}
	}
	
	/**
	 * 连接日志表获取分类数据以二维数组返回
	 *
	 * @access  public
	 * @return  array
	 */
	public function getCatArray() {
	
		$sql = "select c.category_id, c.parent_id, c.category_url, c.category_title, c.category_sort, c.category_isshow,
		       c.category_seoti, c.category_seokw, c.category_seodesc, count(s.category_id) as has_children ".
               " from ".C('DB_PREFIX')."category as c ".
               " left join ".C('DB_PREFIX')."category as s on s.parent_id = c.category_id ".
               " group by c.category_id ".
               ' order by c.parent_id, c.category_sort asc ';	
		$res = $this->query($sql);
		
		/*$sql = "select category_id, count(*) as posts_num " .
               " from ".C('DB_PREFIX')."posts ".
               " where posts_status <> 0 " .
               " group by category_id";
		$res2 = $this->query($sql);*/
		
		$sql = "select p.category_id, count(*) as posts_num " .
               " from ".C('DB_PREFIX')."posts as p , ".C('DB_PREFIX')."category as c ".
               " where p.category_id = c.category_id and posts_status <> 0 " .
               " group by p.category_id";
		$res2 = $this->query($sql);	
		
		$newres = array();
		foreach( $res as $k=>$v) {
			$newres[$v['category_id']] = $v['posts_num'];
			foreach($res2 as $ks=>$vs) {
				if ($v['category_id'] == $vs['category_id']) {
					$newres[$v['category_id']] += $vs['posts_num'];
				}
			}
		}

		foreach ($res as $k=>$v) {
			$res[$k]['posts_num'] = !empty($newres[$v['category_id']]) ? $newres[$v['category_id']] : 0;
		}
		
		return $res;
	}
	
	/**
	 * 过滤和排序所有分类，返回一个带有缩进级别的数组
	 *
	 * @access  private
	 * @param   int     $cat_id     上级分类ID
	 * @param   array   $arr        含有所有分类的数组
	 * @param   int     $level      级别
	 * @return  void
	 */
	public function getCatOptions($arr, $spec_cat_id = 0) {
		static $cat_options = array();
		$path = ROOT_PATH.STATIC_CACHES_DIR;
		if (isset($cat_options[$spec_cat_id])) {
			return $cat_options[$spec_cat_id];
		}

		if (!isset($cat_options[0])) {
			$level = $last_cat_id = 0;
			$options = $cat_id_array = $level_array = array();
			/*if (file_exists($path.'cat_option_static.php')) {
				   $data = require_once ($path.'cat_option_static.php');
				}*/
			//if ($data == false) {
				while (!empty($arr))
				{
					foreach ($arr as $key => $value)
					{
						$cat_id = $value['category_id'];
						if ($level == 0 && $last_cat_id == 0) {
							if ($value['parent_id'] > 0) {
								break;
							}
	
							$options[$cat_id]          = $value;
							$options[$cat_id]['level'] = $level;
							$options[$cat_id]['id']    = $cat_id;
							$options[$cat_id]['name']  = $value['category_title'];
							unset($arr[$key]);
	
							if ($value['has_children'] == 0) {
								continue;
							}
							$last_cat_id  = $cat_id;
							$cat_id_array = array($cat_id);
							$level_array[$last_cat_id] = ++$level;
							continue;
						}
	
						if ($value['parent_id'] == $last_cat_id) {
							$options[$cat_id]          = $value;
							$options[$cat_id]['level'] = $level;
							$options[$cat_id]['id']    = $cat_id;
							$options[$cat_id]['name']  = $value['category_title'];
							unset($arr[$key]);
	
							if ($value['has_children'] > 0) {
								if (end($cat_id_array) != $last_cat_id) {
									$cat_id_array[] = $last_cat_id;
								}
								$last_cat_id    = $cat_id;
								$cat_id_array[] = $cat_id;
								$level_array[$last_cat_id] = ++$level;
							}
						} 
						elseif ($value['parent_id'] > $last_cat_id) {
							break;
						}
					}
	
					$count = count($cat_id_array);
					if ($count > 1) {
						$last_cat_id = array_pop($cat_id_array);
					} 
					elseif ($count == 1) {
						if ($last_cat_id != end($cat_id_array)) {
							$last_cat_id = end($cat_id_array);
						} else {
							$level = 0;
							$last_cat_id = 0;
							$cat_id_array = array();
							continue;
						}
					}
	
					if ($last_cat_id && isset($level_array[$last_cat_id])) {
						$level = $level_array[$last_cat_id];
					} else {
						$level = 0;
					}
				}
				
				//写入静态缓存文件
				f_static_cache('cat_option_static',$options ,$path); 
			//} else {
				//$options = $data;
			//}	
			$cat_options[0] = $options;
		} else {
			$options = $cat_options[0];
		}

		if (!$spec_cat_id) {
			return $options;
		} else {
			if (empty($options[$spec_cat_id])) {
				return array();
			}
			$spec_cat_id_level = $options[$spec_cat_id]['level'];
			foreach ($options as $key => $value) {
				if ($key != $spec_cat_id) {
					unset($options[$key]);
				} else {
					break;
				}
			}
			$spec_cat_id_array = array();
			foreach ($options as $key => $value) {
				if (($spec_cat_id_level == $value['level'] && $value['category_id'] != $spec_cat_id) || ($spec_cat_id_level > $value['level'])) {
					break;
				} else {
					$spec_cat_id_array[$key] = $value;
				}
			}
			$cat_options[$spec_cat_id] = $spec_cat_id_array;
		
			return $spec_cat_id_array;
		}
	}
	
	/**
	 * 获取分类数据
	 *
	 * @access  public
	 * @param   
	 * @return  array
	 */
	public function getCatDate($cat_id) {
	
		$path = ROOT_PATH.STATIC_CACHES_DIR;
	
		if (file_exists($path.'cat_option_static.php')) {
		   $cat_option = f_static_cache('cat_option_static','',$path);	   
		} else {
			if (file_exists($path.'category_static.php')) {
				$data = f_static_cache('category_static','',$path);			
			} else {
				$data = $this->getCatArray();
			}
			f_static_cache('category_static',$data ,$path); 		
			$cat_option = $this->getCatOptions($data,$cat_id);
			//f_static_cache('cat_option_static',$cat_option ,$path);
		}
		return $cat_option;	
	}
	
	/**
	 * 写入静态缓存文件(disabled)
	 *
	 * @access  public
	 * @param 
	 * @return  void
	 */
    public function rewriteStatic() {
		$data = $this->getCatArray();
		$cat_option = $this->getCatOptions($data);
		f_static_cache('category_static',$data ,$path); 
		//f_static_cache('cat_option_static',$cat_option ,$path); 	
	}
	
	/**
	 * 获得指定分类下的子分类
	 *
	 * @access  public
	 * @param   array   $arr        二维数组形式的分类数据
	 * @param   int     $cat_id     分类的ID,默认为父ID
	 * @param   int     $selected   当前选中分类的ID
	 * @param   int     $level      限定返回的级数。为0时返回所有级数
	 * @param   boolean $re_type    返回的类型: 值为真时返回下拉列表,否则返回数组
	 * @param   int     $is_show_all 如果为true显示所有分类，如果为false隐藏不可见分类。
	 * @return  mix
	 */
    public function getCatList($cat_id = 0, $selected = 0, $level = 0, $re_type = true, $is_show_all = true) {
	
	    $arr = $this->getCatDate($cat_id);
		
		$children_level = 99999; //大于这个分类的将被删除
		/*隐藏不可见分类*/
		if ($is_show_all == false) {
			foreach ($arr as $key => $val) {
				if ($val['level'] > $children_level) {
					unset($arr[$key]);
				} else {
					if ($val['category_isshow'] == 0) {
						unset($arr[$key]);
						if ($children_level > $val['level']) {
							$children_level = $val['level']; //标记一下，这样子分类也能删除
						}
					} else {
						$children_level = 99999; //恢复初始值
					}
				}
			}
		}
		
		/* 截取到指定的缩减级别 */
		if ($level > 0) {
			if ($cat_id == 0) {
				$end_level = $level;
			} else {
				$first_item = reset($arr); // 获取第一个元素
				$end_level  = $first_item['level'] + $level;
			}
	
			/* 保留level小于end_level的部分 */
			foreach ($arr as $key => $val) {
				if ($val['level'] >= $end_level) {
					unset($arr[$key]);
				}
			}
		}
		
		if ($re_type) {
		
			foreach ($arr as $cat) {
				$this->catString .= "<option value='{$cat['category_id']}' ";
				$this->catString .= ($cat['category_id'] == $selected) ? "selected='selected'" : '';
				$this->catString .= ">";
				if ($cat['level'] > 0) {
					$this->catString .= str_repeat('&nbsp;', $cat['level'] * 4);
				}
				$this->catString .= "{$cat['category_title']}</option>";	
			}
			
			return $this->catString;
			
		} else {
			foreach ($arr as $key => $cat) {
				$arr[$key]['url'] = C('blog_domain').$cat['category_url'].'/';
			}

			return $arr;
        }
    }
	
	/**
	 * 获取指定子类的上级所有父类的固定链接字符串
	 * 例如: html-table-tr-td
	 * @access  public
	 * @param   int     $cat_id     指定分类ID
	 * @return  string
	 */
    public function getCatUrl($cat_id) {
		if (!isset($cat_id)) return false;
		$path = ROOT_PATH.STATIC_CACHES_DIR;
		if (file_exists($path.'category_static.php')) {
			$data = f_static_cache('category_static','',$path);
		} else {
			$data = $this->getCatArray();
		}	
		$arr = $this->getCatOptions($data,$cat_id);
		if ($p = $arr[$cat_id]['parent_id']) {
			$this->catUrlString[] = $arr[$cat_id]['name'];
			$this->getCatUrl($p);
		} else {
			$this->catUrlString[] = $arr[$cat_id]['name'];
		}
		krsort($this->catUrlString);
		foreach ($this->catUrlString as $cat) {
			$string .= $cat.'-';
		}
		$string =  (strrpos($string, '-')) ? $string : '';
		return $string;
	}

}

?>